package com.ruoyi.base.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.ruoyi.base.VO.ProcessDisplayVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.ResponseData;

import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.validation.Valid;
import javax.servlet.http.HttpServletResponse;

import org.snaker.engine.access.Page;
import org.snaker.engine.entity.*;
import org.snaker.engine.entity.Process;
import org.snaker.engine.model.TaskModel;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.base.domain.BaseProcess;
import com.ruoyi.base.service.IBaseProcessService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * Snaker流程Controller
 * 
 * @author ruoyi
 * @date 2022-10-17
 */
@Api(value = "Snaker流程",tags = "Snaker流程")
@ApiSupport(author = "ruoyi",order = 10)
@RestController
@RequestMapping("/baseProcess/baseProcess")
public class BaseProcessController extends BaseController
{
    @Autowired
    private IBaseProcessService baseProcessService;

    /**
     * 查询Snaker流程列表
     */
    @ApiOperation(value = "查询Snaker流程列表",notes = "查询Snaker流程列表")
    @ApiOperationSupport(order = 10)
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:list')")
    @GetMapping("/list")
    public TableDataInfo<BaseProcess> list(BaseProcess baseProcess)
    {
        startPage();
        List<BaseProcess> list = baseProcessService.selectBaseProcessList(baseProcess);
        return getDataTable(list);
    }

    /**
     * 导出Snaker流程列表
     */
    @ApiOperation(value = "导出Snaker流程列表",notes = "导出Snaker流程列表")
    @ApiOperationSupport(order = 20)
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:export')")
    @Log(title = "Snaker流程", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BaseProcess baseProcess)
    {
        List<BaseProcess> list = baseProcessService.selectBaseProcessList(baseProcess);
        ExcelUtil<BaseProcess> util = new ExcelUtil<BaseProcess>(BaseProcess.class);
        util.exportExcel(response, list, "Snaker流程数据");
    }

    /**
     * 获取Snaker流程详细信息
     */
    @ApiOperation(value = "获取Snaker流程详细信息",notes = "获取Snaker流程详细信息")
    @ApiOperationSupport(order = 30)
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:query')")
    @GetMapping(value = "/{id}")
    public ResponseData<BaseProcess> getInfo(@PathVariable("id") Long id)
    {
        return ResponseData.success(baseProcessService.selectBaseProcessById(id));
    }

    /**
     * 新增Snaker流程
     */
    @ApiOperation(value = "新增Snaker流程",notes = "新增Snaker流程")
    @ApiOperationSupport(order = 40,ignoreParameters = {"baseProcess.id"})
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:add')")
    @Log(title = "Snaker流程", businessType = BusinessType.INSERT)
    @PostMapping
    @RepeatSubmit
    public ResponseData add(@RequestBody @Valid @ApiParam(required=true) BaseProcess baseProcess)
    {
        int i = baseProcessService.insertBaseProcess(baseProcess);
        if(i>0){
            //返回主键
            return ResponseData.success(baseProcess.getId());
        }else{
            return ResponseData.error();
        }
    }

    /**
     * 修改Snaker流程
     */
    @ApiOperation(value = "修改Snaker流程",notes = "修改Snaker流程")
    @ApiOperationSupport(order = 50)
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:edit')")
    @Log(title = "Snaker流程", businessType = BusinessType.UPDATE)
    @PutMapping
    @RepeatSubmit
    public ResponseData edit(@RequestBody @Valid @ApiParam(required=true) BaseProcess baseProcess)
    {
        int i = baseProcessService.updateBaseProcess(baseProcess);
        if(i>0){
            //返回主键
            return ResponseData.success(baseProcess.getId());
        }else{
            return ResponseData.error();
        }
    }

    /**
     * 删除Snaker流程
     */
    @ApiOperation(value = "删除Snaker流程",notes = "删除Snaker流程")
    @ApiOperationSupport(order = 60)
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:remove')")
    @Log(title = "Snaker流程", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public ResponseData remove(@PathVariable Long[] ids)
    {
        //return toResult(baseProcessService.deleteBaseProcessByIds(ids));
        //逻辑删除
        return toResult(baseProcessService.setDeleteByIds(ids));
    }

    /**
     * 查询Snaker流程列表---不进行分页
     */
    @ApiOperation(value = "查询Snaker流程列表---不进行分页",notes = "查询Snaker流程列表---不进行分页")
    @ApiOperationSupport(order = 70)
    @PreAuthorize("@ss.hasPermi('baseProcess:baseProcess:list')")
    @PostMapping("/getDataList")
    public ResponseData<List<BaseProcess>> getDataList(@RequestBody BaseProcess baseProcess)
    {
        List<BaseProcess> list = baseProcessService.selectBaseProcessList(baseProcess);
        return ResponseData.success(list);
    }

    /**
     * 发布流程
     * @param id
     * @return
     */
    @PutMapping("/processPublish/{id}")
    public ResponseData processPublish(@PathVariable Long id){
        baseProcessService.processPublish(id);
        return ResponseData.success();
    }

    /**
     * 查询流程的所有节点
     * @param processId
     * @return
     */
    @GetMapping("/processNodes/{processId}")
    public ResponseData getProcessNodes(@PathVariable String processId){
        List<TaskModel> processNodes = baseProcessService.getProcessNodes(processId);
        return ResponseData.success(processNodes);
    }
    /**
     * 发起流程
     * @param id
     * @return
     */
    @PutMapping("/processStart/{id}")
    public ResponseData<Order> processStart(@PathVariable Long id, @RequestBody Map<String,Object> params){
        Order order = baseProcessService.processStart(id,params);
        return ResponseData.success(order);
    }

    /**
     * 查询当前用户的待办任务
     * @return
     */
    @GetMapping("/getUserTasks")
    public ResponseData getUserTasks(Page<WorkItem> page){
        baseProcessService.getUserTask(page);
        return ResponseData.success(page);
    }

    /**
     * 查询流程进度展示数据
     * @param processId
     * @return
     */
    @GetMapping("/getProcessDsiplay")
    public ResponseData<ProcessDisplayVO> getProcessDsiplay(String processId,String orderId) throws SQLException {
        //流程定义--包含所有的任务定义
        Process processById = baseProcessService.getProcessById(processId);
        Blob content = processById.getContent();
        String processInfo = new String(content.getBytes(1,(int)content.length()));
        //已完成任务
        List<HistoryTask> historyTasks = baseProcessService.getHistoryTasks(orderId);
        //正在进行的任务
        List<Task> activeTasks = baseProcessService.getActiveTasks(orderId);
        List<String> historyNodeNames = new ArrayList<>();
        for(HistoryTask historyTask : historyTasks){
            historyNodeNames.add(historyTask.getTaskName());
        }
        List<String> activeNodeNames = new ArrayList<>();
        for(Task task : activeTasks){
            activeNodeNames.add(task.getTaskName());
        }

        ProcessDisplayVO processDisplayVO = new ProcessDisplayVO();
        processDisplayVO.setProcessInfo(processInfo);
        processDisplayVO.setHistoryNodeNames(historyNodeNames);
        processDisplayVO.setActiveNodeNames(activeNodeNames);
        return ResponseData.success(processDisplayVO);
    }
}
